const express = require('express');
const router = express.Router();
const pool = require('../db');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const crypto = require('crypto');
const authMiddleware = require('../middleware/auth');

// POST /api/login
router.post('/login', async (req, res) => {
  const { username, password } = req.body;
  if (!username || !password) return res.status(400).json({ message: 'username and password required' });
  try {
    // join with atb_role to get role_name so frontend can display it immediately after login
    const [rows] = await pool.query('SELECT u.id, u.user_name, u.pwd, u.role_id, r.role_name FROM atb_user u LEFT JOIN atb_role r ON u.role_id = r.id WHERE u.user_name = ?', [username]);
    if (rows.length === 0) return res.status(401).json({ message: 'Invalid credentials' });
    const user = rows[0];
    // detect MD5 (32 hex chars) and compare, otherwise fall back to bcrypt
    let match = false;
    let usedMd5 = false;
    if (/^[a-f0-9]{32}$/i.test(user.pwd)) {
      const md5 = crypto.createHash('md5').update(password).digest('hex');
      match = md5 === user.pwd;
      usedMd5 = true;
    } else {
      match = await bcrypt.compare(password, user.pwd);
    }
    if (!match) return res.status(401).json({ message: 'Invalid credentials' });

    // If the password was stored as MD5 and matched, migrate to bcrypt hash
    if (usedMd5) {
      try {
        const newHash = await bcrypt.hash(password, 10);
        await pool.query('UPDATE atb_user SET pwd = ? WHERE id = ?', [newHash, user.id]);
        // optional: log migration
        console.log(`Migrated user ${user.user_name} password from MD5 to bcrypt.`);
      } catch (e) {
        console.error('Failed to migrate MD5 password to bcrypt for user', user.user_name, e);
        // don't fail the login — migration is best-effort
      }
    }

    const token = jwt.sign({ id: user.id, username: user.user_name, role_id: user.role_id,role_name:user.role_name }, process.env.JWT_SECRET, { expiresIn: '8h' });

    // Log successful login to atb_log table (best-effort, do not block login on failure)
    (async () => {
      try {
        // get client IP (respect X-Forwarded-For when behind proxy)
        const xf = req.headers['x-forwarded-for'];
        const ip = (typeof xf === 'string' && xf.split(',')[0].trim()) || req.ip || (req.connection && req.connection.remoteAddress) || null;
        const message = `${user.user_name} 登录`;
        const obj = {
          migratedFromMd5: usedMd5 || false,
          method: 'password'
        };
        // produce a MySQL DATETIME string for Beijing time (UTC+8)
        const beijingDatetime = (() => {
          const beijingMs = Date.now() + 8 * 3600 * 1000;
          const d = new Date(beijingMs);
          const YYYY = d.getUTCFullYear();
          const MM = String(d.getUTCMonth() + 1).padStart(2, '0');
          const DD = String(d.getUTCDate()).padStart(2, '0');
          const hh = String(d.getUTCHours()).padStart(2, '0');
          const mm = String(d.getUTCMinutes()).padStart(2, '0');
          const ss = String(d.getUTCSeconds()).padStart(2, '0');
          return `${YYYY}-${MM}-${DD} ${hh}:${mm}:${ss}`;
        })();
        await pool.query(
          'INSERT INTO atb_log (time_stamp, message, user_id, ip, tp, obj_json) VALUES (?, ?, ?, ?, ?, ?) ',
          [beijingDatetime, message, user.id, ip, 'login', JSON.stringify(obj)]
        );
      } catch (logErr) {
        console.error('Failed to write login log for user', user && user.user_name, logErr);
      }
    })();

    // include role_name (may be null) so frontend can show role immediately
    res.json({ token, user: { id: user.id, username: user.user_name, role_id: user.role_id, role_name: user.role_name || null } });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Server error' });
  }
});

// GET /api/me
router.get('/me', authMiddleware, async (req, res) => {
  try {
    // return role_name as well to simplify frontend logic
    const [rows] = await pool.query('SELECT u.id, u.user_name AS username, u.role_id, r.role_name FROM atb_user u LEFT JOIN atb_role r ON u.role_id = r.id WHERE u.id = ?', [req.user.id]);
    if (rows.length === 0) return res.status(404).json({ message: 'User not found' });
    res.json({ user: rows[0] });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Server error' });
  }
});

module.exports = router;